package org.intellij.plugins.junit4;

import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.DataKeys;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.util.PsiTreeUtil;
import org.apache.log4j.Logger;

/**
 * @author tomichj
 */
public class SelectedFile
{
    private final Logger log = Logger.getLogger("CONSOLE-WARN");
    private final Project project;


    public SelectedFile(AnActionEvent event)
    {
        this(event.getDataContext());
    }

    public SelectedFile(DataContext dataContext)
    {
        this(DataKeys.PROJECT.getData(dataContext));
    }

    public SelectedFile(Project project)
    {
        this.project = project;
    }

    public JavaMethod currentMethod()
    {
        PsiMethod psiMethod = currentPsiMethod();
        if (psiMethod == null) return null;
        return new JavaMethod(psiMethod);
    }

    public PsiMethod currentPsiMethod()
    {
        PsiFile psiFile = selectedPsiFile();
        if (psiFile == null) return null;
//        log.debug("psiFile=" + psiFile);

        int offset = selectedTextEditor().getCaretModel().getOffset();
        PsiElement currentElement = psiFile.findElementAt(offset);
        if (currentElement == null) return null;
//        log.warn("currentElement=" + currentElement);

        PsiElement method = PsiTreeUtil.getParentOfType(currentElement, PsiMethod.class);
//        log.warn("parentMethod=" + method);

        // todo check for inner classage
        
        return (PsiMethod) method;
    }

//    public PsiMethod nearestMethod()
//    {
//        PsiFile psiFile = selectedPsiFile();
//        if (psiFile == null) return null;
//        log.debug("psiFile=" + psiFile);
//
//        int offset = selectedTextEditor().getCaretModel().getOffset();
//        PsiElement currentElement = psiFile.findElementAt(offset);
//        if (currentElement == null) return null;
//        log.warn("currentElement=" + currentElement);
//
//        PsiElement method = PsiTreeUtil.getParentOfType(currentElement, PsiMethod.class);
//        log.warn("parentMethod=" + method);
//        // check for inner classage?
//        if (method != null) return (PsiMethod) method;
//
//        method = PsiTreeUtil.getPrevSiblingOfType(currentElement, PsiMethod.class);
//        log.warn("prevSibling=" + method);
//        if (method != null) return (PsiMethod) method;
//
//        method = PsiTreeUtil.getNextSiblingOfType(currentElement, PsiMethod.class);
//        log.warn("nextSibling=" + method);
//        return (PsiMethod) method;
//    }


    public JavaFile selectedFile()
    {
        JUnitProjectComponent compy = JUnitProjectComponent.getProjectComponent(project);
        JavaFileFactory fileFactory = compy.fileFactory();

        PsiFile file = selectedPsiFile();
        if (file == null) return null;
        
        return fileFactory.create(file);
    }

    public PsiFile selectedPsiFile()
    {
        PsiDocumentManager mgr = PsiDocumentManager.getInstance(project);

        Editor editor = selectedTextEditor();
        if (editor == null) return null;

        Document document = editor.getDocument();
        if (document == null) return null;

        return mgr.getPsiFile(document);
    }


    public Editor selectedTextEditor()
    {
        return FileEditorManager.getInstance(project).getSelectedTextEditor();
    }

}
